package com.plm.k8s.myk8sapi.util;

import cn.hutool.core.util.ClassUtil;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author 潘磊明
 * 版本号：1.0
 * 创建日期：2021/7/21 9:09
 */
public class MyBeanUtil {

    /**
     * bean转换成map
     * 由于hutool不支持需求故重新实现，递归对象，为null的键不存入map中
     * @param bean
     * @return
     */
    public static Map<String, Object> bean2Map(Object bean) throws Exception {
        if (bean == null) return null;
        Class clazz = bean.getClass();
        if (ClassUtil.isBasicType(clazz) || String.class == clazz) throw new Exception("不能是基础类型");
        Map<String, Object> map = new LinkedHashMap<>();
        List<Field> fields = getAllFieldsIncludeParent(clazz);
        Method method;
        Object value;
        for (Field field : fields) {
            try {
                method = clazz.getMethod(getGetMethodNameByField(field));
            } catch (Exception e) {
                continue;
            }
            value = method.invoke(bean);
            if (value == null) continue;
            if (ClassUtil.isBasicType(field.getType()) || String.class == field.getType() || value instanceof Map) {
                map.put(field.getName(), value);
            } else if (value instanceof List) {
                List list = new LinkedList();
                Class tClazz;
                Map<String, Object> tmp;
                for (Object obj : (List) value) {
                    tClazz = obj.getClass();
                    if (ClassUtil.isBasicType(tClazz) || String.class == tClazz || obj instanceof Map) {
                        list.add(obj);
                    } else {
                        tmp = bean2Map(obj);
                        list.add(tmp);
                    }
                }
                map.put(field.getName(), list);
            } else {
                Map<String, Object> tmp = bean2Map(value);
                map.put(field.getName(), tmp);
            }
        }
        return map;
    }

    /**
     * 获取所有的字段，包括本身及父类，不包括Object
     * @param clazz
     * @return
     */
    private static List<Field> getAllFieldsIncludeParent(Class clazz) {
        List<Field> list = new LinkedList<>();
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            list.add(fields[i]);
        }
        // 如果父类不是Object，就继续查找
        if (!clazz.getSuperclass().getName().equals(Object.class.getName())) {
            List<Field> tmp = getAllFieldsIncludeParent(clazz.getSuperclass());
            list.addAll(tmp);
        }
        return list;
    }

    /**
     * 获取属性的get方法
     * @param field
     * @return
     */
    public static String getGetMethodNameByField(Field field) {
        return String.format("get%s", StringUtils.capitalize(field.getName()));
    }
}
